﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web;

namespace Common
{
    public static class HttpContextExtensions
    {
        /// <summary>
        /// 上传文件，存储到指定路径并返回文件的相对路径
        /// </summary>
        /// <param name="request"></param>
        /// <param name="exts">后缀名限制</param>
        /// <param name="files">返回de文件对路径</param>
        /// <param name="errMsg">错误提示</param>
        /// <param name="path">保存路径</param>
        public static bool SaveUploadFiles(this HttpRequest request, List<string> exts, out List<string> files, out string errMsg, string path)
        {
            errMsg = "成功";
            files = new List<string>();
            try
            {
                List<string> err = new List<string>();
                for (int i = 0; i < request.Files.Count; i++)
                {
                    HttpPostedFile file = request.Files[i];
                    string ext = file.GetFileExtension();
                    if (!exts.Contains(ext))
                        err.Add(ext);
                }
                if (err.Count > 0)
                {
                    errMsg = $"不支持文件类型：{string.Join(", ", err)}";
                    return false;
                }
                if (!Directory.Exists(path))
                    Directory.CreateDirectory(path);

                for (int i = 0; i < request.Files.Count; i++)
                {
                    HttpPostedFile file = request.Files[i];
                    string fileName = $"{path}\\{Guid.NewGuid().ToString("N")}_{file.FileName}";

                    file.SaveAs(fileName);
                    string url = fileName.Substring(fileName.IndexOf("\\upload"));
                    files.Add(url);
                }
                return true;
            }
            catch (Exception e)
            {
                errMsg = $"异常：{e.Message}";
                return false;
            }
        }

        //List<string> exts = new List<string> { ".jpg", ".doc", ".xlsx" };
        //List<string> files;
        //string msg = "";
        //HttpContext.Current.Request.SaveUploadFiles(exts, out files, out msg, path);



        /// <summary>
        /// 上传单个文件，获取文件流
        /// </summary>
        /// <param name="request"></param>
        /// <param name="exts">后缀名限制</param>
        /// <param name="ext">文件后缀名</param>
        /// <param name="errMsg">错误提示</param>
        /// <returns></returns>
        public static Stream GetUploadFileStream(this HttpRequest request, List<string> exts, out string ext, out string errMsg)
        {
            errMsg = "成功";
            ext = ".";
            if (HttpContext.Current.Request.Files.Count == 0)
            {
                errMsg = "未上传文件";
                return null;
            }
            HttpPostedFile file = HttpContext.Current.Request.Files[0];
            ext = file.GetFileExtension();
            if (!exts.Contains(ext))
            {
                errMsg = $"不支持文件类型：{ext}";
                return null;
            }
            return file.InputStream;
        }

        //string ext, errMsg;
        //Stream stream = HttpContext.Current.Request.GetUploadFileStream(new List<string> { ".xls", ".xlsx" }, out ext, out errorMsg);



        /// <summary>
        /// 获取上传文件的后缀名
        /// </summary>
        /// <param name="file"></param>
        /// <returns>如：.jpg</returns>
        /// <exception cref="ArgumentNullException"></exception>
        static string GetFileExtension(this HttpPostedFile file)
        {
            if (file == null)
                throw new ArgumentNullException(nameof(file));

            string fileName = file.FileName;

            // 获取最后一个点的位置
            int lastDotIndex = fileName.LastIndexOf('.');

            // 如果没有点或者点在文件名的开始位置，则没有后缀名
            if (lastDotIndex < 1)
                return string.Empty;

            // 获取后缀名：.jpg
            string extension = fileName.Substring(lastDotIndex);
            return extension;
        }





        /// <summary>
        /// 文件下载
        /// 需判断文件是否存在
        /// </summary>
        /// <param name="response"></param>
        /// <param name="filename"></param>
        public static void DownloadFile(this HttpResponse response, string filename)
        {
            if (!File.Exists(filename)) {
                string file = Path.GetFileName(filename);
                response.SetResponseMessage($"文件：{file}不存在！", 404);
                return;
            }

            FileStream fs = new FileStream(filename, FileMode.Open);
            byte[] bytes = new byte[(int)fs.Length];
            fs.Read(bytes, 0, bytes.Length);
            fs.Close();
            response.ContentType = "application/octet-stream";
            //通知浏览器下载文件
            response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(Path.GetFileName(filename), Encoding.UTF8));
            response.BinaryWrite(bytes);
            response.Flush();
            response.End();
        }





        /// <summary>
        /// 设置回复报文
        /// </summary>
        /// <param name="Response"></param>
        /// <param name="message"></param>
        /// <param name="code"></param>
        public static void SetResponseMessage(this HttpResponse Response, string message, int code)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(message);
            Response.ContentType = "text/plain; charset=UTF-8";
            Response.BinaryWrite(bytes);
            Response.StatusCode = code;
            Response.Flush();
            Response.End();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context">json字符串</param>
        /// <param name="statusCode">Http状态码，默认200</param>
        /// <returns></returns>
        public static HttpResponseMessage SetHttpResponseMessage(string context, HttpStatusCode statusCode = HttpStatusCode.OK)
        {
            HttpResponseMessage message = new HttpResponseMessage
            {
                Content = new StringContent(context, Encoding.UTF8, "application/json"),
                StatusCode = statusCode
            };
            return message;
        }
    }
}